package errorCode

import (
	"encoding/json"
)

var _ Error = (*err)(nil)

type Error interface {
	// i 为了避免被其他包实现
	i()
	// WithData 设置成功时返回的数据
	WithData(data interface{}) Error
	// ToValue 返回当前结构体
	ToValue() err
	// ToString 返回 JSON 格式的错误详情
	ToString() string
	// SetMsg 设置错误信息
	SetMsg(msg string) Error
	// ClearData 清空附加数据
	ClearData()Error
}

type err struct {
	Code int         `json:"code"`           // 业务编码
	Msg  string      `json:"msg"`            // 错误描述
	Data interface{} `json:"data,omitempty"` 			// 成功时返回的数据
}

func NewError(code int, msg string) Error {
	myErr := err{
		Code: code,
		Msg: msg,
		Data: nil,
	}
	return myErr
}

func (e err) i() {}

// WithData
// 附加数据信息
func (e err) WithData(data interface{}) Error {
	e.Data = data
	return e
}

// SetMsg
// 设置错误信息
func (e err) SetMsg(msg string)Error{
	e.Msg = msg
	return e
}

// ClearData
// 清空附加数据
func (e err) ClearData()Error{
	e.Data = nil
	return e
}

// ToValue
// 返回当前结构体
func (e err)ToValue() err {
	return err{
		Code: e.Code,
		Msg:  e.Msg,
		Data: e.Data,
	}
}

// ToString
// 返回 JSON 格式的错误详情
func (e err) ToString() string {
	err := &struct {
		Code int         `json:"code"`
		Msg  string      `json:"msg"`
		Data interface{} `json:"data"`
	}{
		Code: e.Code,
		Msg:  e.Msg,
		Data: e.Data,
	}

	raw, _ := json.Marshal(err)
	return string(raw)
}
